﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MagicArena.framework.action;
using MagicArena.framework.toon;
using MagicArena.framework.state;
using MagicArena.framework.physics.util;

namespace MagicArena.impl.action
{
    public class ActionMove : AAction
    {
        private const string NameFormat = "ActionMove-{0}";
        private const float MoveAmount = 2;

        private Direction _Direction;

        private State XChange, YChange;
        private float ellapseTime = 0;

        public enum Direction { Up=0, Right=1, Down=2, Left=3, ToTarget=4}

        public ActionMove(Direction d) : base(string.Format(NameFormat, d.ToString()))
        {
            float xAmnt=0, yAmnt=0;
            switch (d)
            {
                case Direction.Up:
                    yAmnt = MoveAmount;
                    break;
                case Direction.Down:
                    yAmnt = -1 * MoveAmount;
                    break;
                case Direction.Right:
                    xAmnt = MoveAmount;
                    break;
                case Direction.Left:
                    xAmnt = -1 * MoveAmount;
                    break;
                case Direction.ToTarget:
                    this._StateChanges.Add(new State(State.Common.TargetDist, MoveAmount));
                    break;
            }

            // Create the states, add them to base class
            XChange = new State(State.Common.Xpos, xAmnt);
            YChange = new State(State.Common.Ypos, yAmnt);
            this._StateChanges.Add(XChange);
            this._StateChanges.Add(YChange);

            // Used at later for referencing
            
            _Direction = d;
        }

        public override void Execute(object target)
        { 
            // Calculate the Xpos and Ypos moves based on target if ToTarget
            if (_Direction == Direction.ToTarget)
            {
                //Get target location
                if (!(target is IPositionState)) throw new ArgumentException("target is not IPositionState, cannot get position to execute");
                IPositionState ps = (IPositionState)target;
                Vector2 tpos = new Vector2(ps.GetXPos().Value, ps.GetYPos().Value);
                Vector2 spos = new Vector2(this.SourceToon.GetXPos().Value, this.SourceToon.GetYPos().Value);

                //Get unit vector
                Vector2 unit = spos.UnitVector(tpos);

                //Update xpos and ypos using unit vector
                XChange.Value = unit.X * MoveAmount;
                YChange.Value = unit.Y * MoveAmount;
            }
            // execute on _Source, not target
            foreach(State s in _StateChanges){
                State ts = State.FindState(this.SourceToon.States, s.Id);
                ts.Value += s.Value;
            }

            // Set XChange and YChange back to 0 so that others don't grab ToTarget moves accidently
            XChange.Value = 0;
            YChange.Value = 0;

            ellapseTime = 0;
        }

        public override void Update(Microsoft.Xna.Framework.GameTime gameTime)
        {
            //TODO Inefficient
            ellapseTime += (float)gameTime.ElapsedGameTime.TotalSeconds;
        }
    }
}
